package Biblioteca

import org.springframework.security.ui.webapp.AuthenticationProcessingFilter
import Contas.Administrador 
import Contas.Usuario 
import Contas.UsuarioComum 
import Biblioteca.Emprestimo
import Biblioteca.Livro
 

class ReservaController {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def index = {
        redirect(action: "list", params: params)
    }
	
	private String getTipoUsuario (){
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		Usuario user = Contas.Usuario.findByUsername(username)
		def tipo
		if (Administrador.get(user.id)==null){
			tipo = "Usuario"
		}else{
			tipo = "Admin"
		}
	return tipo
	}

    def list = {
		
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		Usuario user = Usuario.findByUsername(username)
		def usuario
		
		if (Administrador.get(user.id)==null){
			usuario = UsuarioComum.get(user.id)
		}else{
			usuario = Administrador.get(user.id)
		}
		def ids = Reserva.executeQuery("select id from Reserva where username = " + "\'" + usuario.username + "\'")
		def reservas = []
		for (id in ids){
			reservas.add(Reserva.get(id))
		}
        params.max = Math.min(params.max ? params.int('max') : 10, 100)
        [reservaInstanceList: reservas, reservaInstanceTotal: Reserva.count(), tipo:this.getTipoUsuario ()]
    }

    def create = {
        def reservaInstance = new Reserva()
        reservaInstance.properties = params
        return [reservaInstance: reservaInstance, tipo:this.getTipoUsuario ()]
    }

    def save = {
		
        def livroInstance = Livro.get(params.id)
		def qtde = Exemplar.executeQuery("select id from Exemplar where isbnItem = " + livroInstance.isbn)
		def emprestados = Emprestimo.executeQuery("select dataDevolucao from Emprestimo where idItem = " + livroInstance.id+" and tipo = 'livro'")
		def reservados = Reserva.executeQuery("select dataReserva, dataDevolucao from Reserva where idItem = " + livroInstance.id)
		def jatemEmprestimo = false
		
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		def dataHoje = new Date()
		def reservaInstance = new Reserva()
		reservaInstance.idItem = Integer.parseInt (params.id)
		reservaInstance.dataReserva = params.dataReserva
		reservaInstance.dataRequisicao = dataHoje
		reservaInstance.dataDevolucao = params.dataDevolucao
		reservaInstance.username = username.toString()
		reservaInstance.titulo = livroInstance.titulo
		reservaInstance.tipo = 'livro'
		
		def emprestimos_usuario = Emprestimo.executeQuery("select id from Emprestimo where login = " + "'" + username.toString() + "'")
		def reservas_usuario = Reserva.executeQuery("select idItem from Reserva where username = " + "'" + username.toString() +"'" )
		
		def emprestadosTotal = emprestados.size()
		def reservadosTotal = reservados.size()
		
		for(emp in emprestados){
			if(reservaInstance.dataReserva.minus(emp.dataDevolucao) > 0){
				emprestadosTotal = 	emprestadosTotal -1		
			}
		}	
		
		for(res in reservados){
			if((res[1].minus(reservaInstance.dataReserva)) > 0)
				reservadosTotal = reservadosTotal -1
			else if((reservaInstance.dataDevolucao.minus(res[0])) > 0)
				reservadosTotal = reservadosTotal -1
		}
		
		
		for (emprestimo in emprestimos_usuario){
			def livro_emprestimo = Emprestimo.executeQuery("select idItem from Emprestimo where idItem = " + emprestimo + " and tipo='livro'")
			if (livro_emprestimo.contains (livroInstance.id)){
				flash.message = "Voce ja possui um emprestimo deste livro."
				jatemEmprestimo = true
			}
		}
		if (reservas_usuario.contains(livroInstance.id)){
			flash.message = "Voce ja possui uma reserva deste livro."
		}else if (!jatemEmprestimo && (qtde.size() - emprestadosTotal - reservadosTotal) > 0){
			reservaInstance.save()
			flash.message = "${message(code: 'Livro Reservado com sucesso!', args: [message(code: 'Livro Reservado com sucesso!', default: 'Livro Reservado com sucesso!'), params.id])}"
			
		}else if (!jatemEmprestimo){
			flash.message = "Nao existe nenhum exemplar disponivel para este Livro."
			
		}
		redirect(action: "show", id: params.id)
    }

    def show = {
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		Usuario user = Contas.Usuario.findByUsername(username)
		def tipo
		if (Administrador.get(user.id)==null){
			tipo = "Usuario"
		}else{
			tipo = "Admin"
		}
        def reservaInstance = Reserva.get(params.id)
        if (!reservaInstance) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'reserva.label', default: 'Reserva'), params.id])}"
            redirect(action: "list")
        }
        else {
            [reservaInstance: reservaInstance, tipo:this.getTipoUsuario ()]
        }
    }

    def edit = {
        def reservaInstance = Reserva.get(params.id)
        if (!reservaInstance) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'reserva.label', default: 'Reserva'), params.id])}"
            redirect(action: "list")
        }
        else {
            return [reservaInstance: reservaInstance, tipo:this.getTipoUsuario ()]
        }
    }

    def update = {
        def reservaInstance = Reserva.get(params.id)
        if (reservaInstance) {
            if (params.version) {
                def version = params.version.toLong()
                if (reservaInstance.version > version) {
                    
                    reservaInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'reserva.label', default: 'Reserva')] as Object[], "Another user has updated this Reserva while you were editing")
                    render(view: "edit", model: [reservaInstance: reservaInstance])
                    return
                }
            }
            reservaInstance.properties = params
            if (!reservaInstance.hasErrors() && reservaInstance.save(flush: true)) {
                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'reserva.label', default: 'Reserva'), reservaInstance.id])}"
                redirect(action: "show", id: reservaInstance.id)
            }
            else {
                render(view: "edit", model: [reservaInstance: reservaInstance, tipo:this.getTipoUsuario ()])
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'reserva.label', default: 'Reserva'), params.id])}"
            redirect(action: "list")
        }
    }

    def delete = {
        def reservaInstance = Reserva.get(params.id)
        if (reservaInstance) {
            try {
                reservaInstance.delete(flush: true)
                flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'reserva.label', default: 'Reserva'), params.id])}"
                redirect(action: "list")
            }
            catch (org.springframework.dao.DataIntegrityViolationException e) {
                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'reserva.label', default: 'Reserva'), params.id])}"
                redirect(action: "show", id: params.id)
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'reserva.label', default: 'Reserva'), params.id])}"
            redirect(action: "list")
        }
    }
}
